﻿using Core.Middleware.StaticFileCacheing;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Middleware.StaticFileCacheing
{
    public class StaticFileCacheMidWare
    {
        private static List<FileCacheHandler> CacheHandlers;

        private readonly RequestDelegate requestDelegate;

        static StaticFileCacheMidWare() 
        {
            CacheHandlers = new List<FileCacheHandler>();

            try
            {
                var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IFileCache))))
                .ToArray();

                foreach (var aHandler in types)
                {
                    var atts = aHandler.CustomAttributes;
                    if (atts?.Count() > 0)
                    {
                        foreach (var att in atts)
                        {
                            if (att.AttributeType == typeof(CacheTopicAttribute))
                            {
                                var _handler = new FileCacheHandler
                                {
                                    Topic = att.ConstructorArguments[0].Value.ToString(),
                                    Handler = (IFileCache)Activator.CreateInstance(aHandler)
                                };
                                CacheHandlers.Add(_handler);
                            }
                        }
                    }
                }
            }
            catch
            {
                CacheHandlers = null;
            }

        }

        public StaticFileCacheMidWare(RequestDelegate requestDelegate)
        {
            this.requestDelegate = requestDelegate;
        }

        public async Task Invoke(HttpContext context)
        {

            // 请求路径
            string requestPath = context.Request.Path.ToString().TrimStart('/');

            // 检测 .json 文件
            var isJson = !string.IsNullOrWhiteSpace(requestPath) && Path.GetExtension(requestPath).Equals(".json");

            if (isJson)
            {
                // 获取请求Token
                var routes = requestPath.TrimEnd(".json".ToCharArray()).Split("/");

                // 验证路由
                if (routes.Length > 1)
                {
                    // 获取Topic
                    var _topic = routes[0];

                    // 检测是否使用缓存路由
                    if (IsUseFileCache(_topic,out IFileCache handler))
                    {
                        // 构造传入参数
                        var param = routes.ToList();
                        
                        // 去除Topic
                        param.Remove(_topic);

                        // 获取缓存
                        var data = handler.Get(param.ToArray());

                        // 设置 ContentType
                        context.Response.ContentType = "application/json; charset=utf-8";

                        await context.Response.WriteAsync(data);
                    }
                    else
                    {
                        await requestDelegate(context);
                    }
                }
                else
                {
                    await requestDelegate(context);
                }
            }
            else
            {
                await requestDelegate(context);
            }

        }

        private bool IsUseFileCache(string topic, out IFileCache _handler) 
        {

            if (string.IsNullOrWhiteSpace(topic))
            {
                _handler = null;
                return false;
            }

            var cache = CacheHandlers.Where(a => a.Topic == topic).FirstOrDefault();

            if (null != cache)
            {
                _handler = cache.Handler;
            }
            else
            {
                _handler = null;
                return false;
            }

            return true;

        }


    }
}
